using EnvDTE;
using Microsoft.Practices.Common;
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Security.Permissions;
using VSSDKAssist.Assets.References.Base;

namespace VSSDKAssist.Assets.References.VisualStudio
{
	/// <summary>
	/// UnboundReference for a project item
	/// </summary>
	[Serializable]
	public class ProjectItemReference : RecipeReferenceBase, IAttributesConfigurable
	{		
		private const string FileExtensionAttribute = "FileExtension";

		private string fileExtension;

		/// <summary>
		/// Constructor of the <see cref="ProjectItemReference"/> that must specify the 
		/// recipe name that will be used by the reference
		/// </summary>
		/// <param name="recipe"></param>
		public ProjectItemReference(string recipe)
			: base(recipe)
		{
		}

		/// <summary>
		/// See <see cref="P:Microsoft.Practices.RecipeFramework.IAssetReference.AppliesTo"/>.
		/// </summary>
		/// <value></value>
		public override string AppliesTo
		{
			get { return Properties.Resources.ProjectItemReference; }
		}

		/// <summary>
		/// Performs the validation of the item passed as target
		/// Returns true if the reference is allowed to be executed in the target
		/// that is if the target is a <see cref="ProjectItem"/> file.
		/// </summary>
		/// <param name="target"></param>
		/// <returns></returns>
		public override bool IsEnabledFor(object target)
		{
			ProjectItem item = target as ProjectItem;

			if(item != null)
			{
				if(!string.IsNullOrEmpty(fileExtension))
				{
					return fileExtension.Equals(Path.GetExtension(item.Name),
						StringComparison.InvariantCultureIgnoreCase);
				}
				else
				{
					return true;
				}
			}
			return false;
		}

		#region ISerializable Members

		/// <summary>
		/// Initializes a new instance of the <see cref="T:ProjectItemReference"/> class.
		/// </summary>
		/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the reference.</param>
		/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")]
		protected ProjectItemReference(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
			fileExtension = info.GetString("FileExtension");
		}

		/// <summary>
		/// Provides a serialization member that derived classes can override to add
		/// data to be stored for serialization.
		/// </summary>
		/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the reference.</param>
		/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
		[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
		protected override void GetObjectData(SerializationInfo info, StreamingContext context)
		{
			base.GetObjectData(info, context);
			info.AddValue("FileExtension", fileExtension);
		}

		#endregion ISerializable Members

		#region IAttributesConfigurable Members

		/// <summary>
		/// Configures the component using the dictionary of attributes specified
		/// in the configuration file.
		/// </summary>
		/// <param name="attributes">The attributes in the configuration element.</param>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")]
		public void Configure(System.Collections.Specialized.StringDictionary attributes)
		{
			if(attributes.ContainsKey(FileExtensionAttribute))
			{
				fileExtension = attributes[FileExtensionAttribute];
			}
		}

		#endregion
	}
}